<?php

/*
 * 用户本地化相关信息
 */

/**
 * 用户本地化相关信息
 *
 * @package system
 * @subpackage location
 * 
 * @author etpasse
 * 
 */
//
//function ip2int($ip){
//    
//    return sprintf("%u", ip2long($ip));
//    
//}
class Handler_location {

    /**
     * 获取酒店搜索框的城市信息。(网站首页、酒店首页、品牌页) 用户最近一次预订的城市
     * 
     * @global object $member_info
     * @return array 
     */
    public static function getHotelSearchParam($member_info='') {
//        return array('city_name'=>'拼音/中文/英文');
//        global $member_info;

        $search_param = hotel_service::get_cookie_para();
        if (!empty($search_param['cityName'])) {
            $search_city_name = urldecode($search_param['cityName']);
        } else {
            if ($member_info->is_login) { //如果登录过
//          mssql主库 用户最近一次预订的城市
                $ms_db = mssql_connect::get(TRUE);
                $sql = 'select top 1 B.City_Name as city_name,B.PKID as city_id from BA_CMS_City as B
						inner join Hotel as H on H.CityId=B.PKID
						inner join HotelOrder as O on O.HotelId = H.HotelId
                     where O.UserId = ' . $member_info->user_id . '	order by O.OrderId desc';
                $cities = $ms_db->get_one($sql);
                if (empty($cities))
                    $cities = self::getHotelCityByIP(Handler_http::getIP(), TRUE);

            } else {
                $cities = self::getHotelCityByIP(Handler_http::getIP(), TRUE);
            }
            $search_city_name = $cities['city_name'];
        }
        if(empty($search_city_name)){
            $search_city_name = '拼音/中文/英文';
        }
        $search_param['cityName'] = $search_city_name;
        return $search_param;
        
    }

    /**
     * 获取机票搜索框的城市信息。
     * @global object $member_info
     * @return array 
     */
    public static function getFlightSearchParam($member_info = '') {
//        return array('', '', date("Y-m-d", time() + 86400 * 7), '', date("Y-m-d", time() + 86400 * 9));        

        $search_city_cookie_name = "search_city";

        $search_city = Handler_http::getCookie($search_city_cookie_name);
        if (!empty($search_city)) {
            $search_city_array = explode("_", $search_city);
            $fromCityName = Flight_static::$AirPort[$search_city_array[0]][0];
            $toCityName = Flight_static::$AirPort[$search_city_array[1]][0];
            $date = $search_city_array[2];
            $to2City = Flight_static::$AirPort[$search_city_array[3]][0];
            $date2 = $search_city_array[4];
        } else {
            $fromCity = self::getFlightCityByIP(Handler_http::getIP(), TRUE);
            if ($member_info->is_login && $member_info->mobile) {
                $toCity = self::getFlightCityByMobile($member_info->mobile, true);
            }
            $fromCityName = is_null($fromCity["city_name"]) ? '' : $fromCity["city_name"];
            $toCityName = is_null($toCity["city_name"]) ? '' : $toCity["city_name"];
            if ($fromCityName == $toCityName) {
                $toCityName = "";
            }

            $to2City = "";
        }

        if (empty($date) || strtotime($date) < time()) {
            $date = date("Y-m-d", time() + 86400 * 7);
            $date2 = date("Y-m-d", time() + 86400 * 9);
        }
        if(empty($date2)){
        	$date2 = date("Y-m-d", strtotime($date) + 86400 * 9);
        }
        return array($fromCityName, $toCityName, $date, $to2City, $date2);
    }

    /**
     * 根据IP取得酒店城市信息 如果城市不存在于本站数据库，则取省会城市
     * 返回数组格式为 array('city_name'=>'北京','std_code'=>100000);
     * 判断返回值是否正确可以用下面格式
     * <code>
     * <?php
     * 
     * $city = Handler_location::getHotelCityByIP($ip)
     * if(!empty($city) && !empty($city['city_name'])){
     * 
     * }elseif(!empty($city['std_code'])){
     * 
     * }else{
     * 
     * }
     * ?>
     * </code>
     * @param str $ip ip地址 
     * @param str $getCapital 是否取省会城市
     * @return NULL | array
     */
    public static function getHotelCityByIP($ip, $getCapital = FALSE) {
        if (!$codes = self::_getStdcodebyIP($ip)) {
            return NULL;
        } else {
            return self::_getCityByCode($codes[0]['std_code'], FALSE, $getCapital);
        }
    }

    /**
     * 根据IP取得机票城市信息 
     * 返回数组格式为 array('city_name'=>'北京','std_code'=>100000); 
     * 判断返回值是否正确可以用下面格式
     * <code>
     * <?php
     * 
     * $city = Handler_location::getFlightCityByIP($ip)
     * if(!empty($city) && !empty($city['city_name'])){
     * 
     * }elseif(!empty($city['std_code'])){
     * 
     * }else{
     * 
     * }
     * ?>
     * </code>
     * @param str $ip  ip地址
     * @param str $getCapital 是否取省会城市
     * @return null | array
     */
    public static function getFlightCityByIP($ip, $getCapital = FALSE) {

        if (!$codes = self::_getStdcodebyIP($ip)) {
            return NULL;
        } else {
            return self::_getCityByCode($codes[0]['std_code'], TRUE, $getCapital);
        }
    }

    /**
     * 根据手机号取的酒店城市信息
     * 返回数组格式为 array('city_name'=>'北京','std_code'=>100000);
     * 判断返回值是否正确可以用下面格式
     * <code>
     * <?php
     * 
     * $city = Handler_location::getHotelCityByMobile($mobile)
     * if(!empty($city) && !empty($city['city_name'])){
     * 
     * }elseif(!empty($city['std_code'])){
     * 
     * }else{
     * 
     * }
     * ?>
     * </code>
     * @param str $mobile 手机号码，支持国家区号形式
     * @param str $getCapital 是否取省会城市
     * @return NULL | array 
     */
    public static function getHotelCityByMobile($mobile, $getCapital = FALSE) {

        if (!$codes = self::_getStdcodeByMobile($mobile)) {
            return NULL;
        } else {
            return self::_getCityByCode($codes[0]['std_code'], FALSE, $getCapital);
        }
    }

    /**
     * 根据手机号取的机票城市信息
     * 返回数组格式为 array('city_name'=>'北京','std_code'=>100000);
     * 判断返回值是否正确可以用下面格式
     * <code>
     * <?php
     * 
     * $city = Handler_location::getFlightCityByMobile($mobile)
     * if(!empty($city) && !empty($city['city_name'])){
     * 
     * }elseif(!empty($city['std_code'])){
     * 
     * }else{
     * 
     * }
     * ?>
     * </code>  
     * 
     * @param str $mobile 手机号码，支持国家区号形式
     * @param str $getCapital 是否取省会城市
     * @return NULL | array 
     */
    public static function getFlightCityByMobile($mobile, $getCapital = FALSE) {

        if (!$codes = self::_getStdcodeByMobile($mobile)) {
            return NULL;
        } else {
            return self::_getCityByCode($codes[0]['std_code'], TRUE, $getCapital);
        }
    }

    /**
     * 根据标准码获得酒店省会城市名
     * @param type $std_code 城市标准码
     * @return type 
     */
    public static function getHotelCapitalCityByCode($std_code) {

        return self::_getCapitalCityByCode($std_code);
    }

    /**
     * 根据标准码获得机票省会城市名
     * @param type $std_code 城市标准码
     * @return type 
     */
    public static function getFlightCapitalCityByCode($std_code) {

        return self::_getCapitalCityByCode($std_code, TRUE);
    }

    /**
     * 根据标准码获得酒店城市名
     * @param type $std_code 城市标准码
     * @return type 
     */
    public static function getHotelCityByCode($std_code) {

        return self::_getCityByCode($std_code);
    }

    /**
     * 根据标准码获得机票城市名
     * @param type $std_code 城市标准码
     * @return type 
     */
    public static function getFlightCityByCode($std_code) {

        return self::_getCityByCode($std_code, TRUE);
    }

    /**
     * 根据酒店城市中文名取得机票城市名
     * 
     * @param str $city_name 酒店城市名
     * @param bool $getCapital 当城市不存在时是否取省会城市
     * 
     * @return array | null
     */
    public static function getFlightCityByHotelCity($city_name, $getCapital = TRUE) {

        $city_info = Handler_city::get_citys($city_name);
        if ($city_info['std_code']) {
            $cities = self::getFlightCityByCode($city_info['std_code']);

            if (!$cities['city_name']) {
                if ($getCapital) {
                    $cities = self::getFlightCapitalCityByCode($city_info['std_code']);
                    if ($cities['city_name'])
                        return $cities;
                }
            } else {
                return $cities;
            }
        }
        return NULL;
    }

    /**
     * 根据酒店城市中文名取得机票城市名
     * 
     * @param str $city_name 机票城市名
     * @param bool $getCapital 当城市不存在时是否取省会城市
     * 
     * @return array | null
     */
    public static function getHotelCityByFlightCity($city_name, $getCapital = TRUE) {


        $Cache_Lite = MemoryCache::getInstance();
        $Cache_key = md5('getHotelCityByFlightCity_' . $city_name . '_' . $getCapital);
        if (!$return = $Cache_Lite->get($Cache_key)) {
            $return = Handler_city::get_citys($city_name);
            if (empty($return)) {
                if ($getCapital) {
                    $db = DB_MySQLi::getInstance(1);
                    $sql = 'select * from cms_std_city where city like \'%' . $db->escapeString($city_name) . '%\' limit 1';
                    $_re = $db->getData_ASSOCS($sql);
                    if ($_re['std_code']) {
                        $_cities = self::getHotelCapitalCityByCode($_re['std_code']);
                        $return = Handler_city::get_citys($_cities['city_name']);
                    }
                }
            }
            $Cache_Lite->set($Cache_key, $return, 864000);
        }
        return $return;
    }

    /**
     * 查询ip库获得城市标准码
     * 
     * @param str $ip ip地址
     * @return boolean | array
     */
    private static function _getStdcodebyIP($ip) {

        $Cache_Lite = MemoryCache::getInstance();
        $Cache_key = md5('_getStdcodebyIP_' . $ip);
        if (!$return = $Cache_Lite->get($Cache_key)) {
//        if (1) {    
            if (self::_checkIP($ip)) {
                $ip_int = Handler_tool::ip2long($ip);
                $db = DB_mysqli::getInstance();
//                $sql = 'select city_id,std_code from wry_ip where ip_start <=' . $ip_int . ' and ip_end >= ' . $ip_int . ' limit 1';
                $sql = 'select city_id,std_code from wry_ip where ip_start <=' . $ip_int .' order by ip_start desc limit 1';
                $return = $db->getData_ASSOCS($sql);
            } else {
                $return = '';
            }

            $Cache_Lite->set($Cache_key, $return, 864000);
        }
        return $return;
    }

    /**
     * 验证ip的合法性
     * 
     * @param str $ip ip地址
     * @return boolean 
     */
    private static function _checkIP($ip) {
        if (!preg_match("/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/", $ip)) {
            return FALSE;
        }
        $iparray = explode('.', $ip);

        if ($iparray[0] == 10 || $iparray[0] == 127 || ($iparray[0] == 192 && $iparray[1] == 168) || ($iparray[0] == 172 && ($iparray[1] >= 16 && $iparray[1] <= 31))) {
            return FALSE;
        } elseif ($iparray[0] > 255 || $iparray[1] > 255 || $iparray[2] > 255 || $iparray[3] > 255) {
            return FALSE;
        }
        return TRUE;
    }

    /**
     * 查询手机库获得城市标准码和手机号所在地
     * 
     * @param str $mobile 手机号码，支持国家区号形式
     * @return bool | array 
     */
    public static function _getStdcodeByMobile($mobile) {

        $Cache_Lite = MemoryCache::getInstance();
        $Cache_key = md5('_getStdcodeByMobile_' . $mobile);
        if (!$return = $Cache_Lite->get($Cache_key)) {

            if (Handler_validate::checkPhone($mobile)) {

                if (!$mobile = Handler_tool::getSimpleCNMobile($mobile)) {
                    $return = '';
                } else {
                    $mob_id = substr($mobile, 0, 7);
                    $db = DB_mysqli::getInstance();

                    $sql = 'select * from mob_location where mob_id = ' . $mob_id . ' limit 1';
                    $return = $db->getData_ASSOCS($sql);
                }
            } else {
                $return = '';
            }
            $Cache_Lite->set($Cache_key, $return, 864000);
        }
        return $return;
    }

    /**
     * 根据标准码获得省会城市名
     * 
     * @param str $std_code 城市标准码
     * @param bool $flight 是不是机票城市
     * @return NULL | array
     */
    private static function _getCapitalCityByCode($std_code, $flight = FALSE) {

        $_specCtiy = self::_getSpecCity();
        $_pre = substr($std_code, 0, 2);

        if ($_specCtiy[$_pre]) {
            return array('city_name' => $_specCtiy[$_pre], 'std_code' => $_pre . '0000'); //机票酒店都是一样的
        } else {
            $_std_code = $_pre . '0100';
            $cities = self::_getCity($_std_code, $flight);
            if ($cities)
                return array('city_name' => $cities[0]['city_name'], 'std_code' => $_std_code);
            else
                return NULL;
        }
    }

    /**
     * 根据标准码获得城市名或省会城市名，如果没有取到城市则返回
     * 
     * @param str $std_code 城市标准码
     * @param bool $flight 是否是机票城市
     * @param bool $getCapital 是否取省会城市
     * @return NULL | array
     */
    private static function _getCityByCode($std_code, $flight = FALSE, $getCapital = FALSE) {
        $std_code = intval($std_code);
        if (empty($std_code))
            return NULL;

        $_specCtiy = self::_getSpecCity();
        $_pre = substr($std_code, 0, 2);

        if ($_specCtiy[$_pre]) {
            return array('city_name' => $_specCtiy[$_pre], 'std_code' => $_pre . '0000');
        } else {

            if (strcasecmp(substr($std_code, -4), '0000') == 0) { //如果std_code为省份名，则返回省会城市
                $std_code = $_pre . '0100';
            }

            $cities = self::_getCity($std_code, $flight);
            if ($cities)
                return array('city_name' => $cities[0]['city_name'], 'std_code' => $std_code);
            else {
                if ($getCapital) {
                    $parent = FALSE;
                    $_suff = substr($std_code, -2);

                    if (strcasecmp($_suff, '00') !== 0) { //三级城市
                        $std_code = substr($std_code, 0, 4) . '00';
                        $cities2 = self::_getCity($std_code, $flight);
                        if ($cities2) {
                            $parent = TRUE;
                        } else {
                            $std_code = $_pre . '0100';
                            $cities2 = self::_getCity($std_code, $flight);
                            if ($cities2) {
                                $parent = TRUE;
                            }
                        }
                    } else {
                        $std_code = $_pre . '0100';
                        $cities2 = self::_getCity($std_code, $flight);
                        if ($cities2) {
                            $parent = TRUE;
                        }
                    }

                    if ($parent)
                        return array('city_name' => $cities2[0]['city_name'], 'std_code' => $std_code);
                    else
                        return array('city_name' => '', 'std_code' => $std_code);
                }else {
                    return array('city_name' => '', 'std_code' => $std_code);
                }
            }
            return NULL;
        }
    }

    /**
     * 根据标准码查询城市 sql 
     * @param int $std_code
     * @param bool $flight 是否机票 
     * @return null 
     */
    private static function _getCity($std_code, $flight = FALSE) {
        $std_code = intval($std_code);
        //如果std_code 不存在 
        if (empty($std_code))
            return NULL;


        $Cache_Lite = MemoryCache::getInstance();
        $Cache_key = md5('_getCity_' . $std_code . '_' . $flight);
        if (!$return = $Cache_Lite->get($Cache_key)) {

            $db = DB_MySQLi::getInstance(1);
            if ($flight) {
                $sql = 'select * from cms_std_city where std_code = ' . $std_code . ' limit 1';
                $_re = $db->getData_ASSOCS($sql);
                $aire = self::_getAirPort();
                foreach ($aire as $row) {
                    if (strpos($_re[0]['city'], $row[0]) !== FALSE) {
                        $return = array(0 => array('city_name' => $row[0]));
                        break;
                    }
                }
            } else {
                $sql = 'select city_id,city_name from cms_cities where std_code = ' . $std_code . ' limit 1';
                
                
                $return = $db->getData_ASSOCS($sql);
            }
            $Cache_Lite->set($Cache_key, $return, 864000);
        }
        return $return;
    }

    /**
     * 单例模式取机票相关静态数据
     * 
     * @staticvar null $airpot
     * @return array 
     */
    private static function _getAirPort() {
        static $airpot = NULL;

        if (NULL == $airpot) {
            require_once DATA_PATH.'Flight_static.class.php';
            $airpot = Flight_static::$AirPort;
        }
        return $airpot;
    }

    /**
     * 标准码对应的直辖市
     * @return array
     */
    private static function _getSpecCity() {

        return array(11 => "北京", 12 => "天津", 31 => "上海", 50 => "重庆");
    }

}

?>
